#pragma GCC diagnostic ignored "-Wunused-result"
#include <iostream>
#include <vector>
#include <map>
#include <string>
using namespace std;
#include <sys/reboot.h>
#include <unistd.h>
#include <string.h>
#include "queue.h"
#include "cJSON.h"

int upgrade(const cJSON *conf, char *buf, int len)
{
	system("sysupgrade /tmp/sys_upgrade.bin");
	reboot(RB_AUTOBOOT);
	return 0;
}

int get_base_info(const cJSON *conf, char *buf, int len)
{
	return 0;
}

int get_network_cfg(const cJSON *conf, char *buf, int len)
{
	char info[1024];
	FILE *f = popen("ubus call network.interface.wisp0 status", "r");
	if (f == NULL) {
		return -1;
	}
	int rlen = fread(info, sizeof(info), 1, f);
	send_msg(SERVICE_QUEUE_RSP, info, rlen);
	pclose(f);
	return 0;
}

int set_network_cfg(const cJSON *conf, char *buf, int len)
{
	cJSON *mode = cJSON_GetObjectItemCaseSensitive(conf, "mode");
	if (mode->valuestring == string("dhcp")) {
		system("uci delete network.wisp0.dns");
		system("uci set network.wisp0.proto='dhcp'");
	} else {
		char cmd[128];
		system("uci set network.wisp0.proto='static'");

		cJSON *ipv4Addr = cJSON_GetObjectItemCaseSensitive(conf, "ipv4Addr");
		snprintf(cmd, sizeof(cmd), "uci set network.wisp0.ipaddr='%s'", ipv4Addr->valuestring);
		system(cmd);

		cJSON *ipv4SubnetMask = cJSON_GetObjectItemCaseSensitive(conf, "ipv4SubnetMask");
		snprintf(cmd, sizeof(cmd), "uci set network.wisp0.netmask='%s'", ipv4SubnetMask->valuestring);
		system(cmd);

		cJSON *ipv4Gateway = cJSON_GetObjectItemCaseSensitive(conf, "ipv4Gateway");
		snprintf(cmd, sizeof(cmd), "uci set network.wisp0.gateway='%s'", ipv4Gateway->valuestring);
		system(cmd);

		cJSON *ipv4DNSPrimary = cJSON_GetObjectItemCaseSensitive(conf, "ipv4DNSPrimary");
		snprintf(cmd, sizeof(cmd), "uci add_list network.wisp0.dns='%s'", ipv4DNSPrimary->valuestring);
		system(cmd);

		cJSON *ipv4DNSSecondary = cJSON_GetObjectItemCaseSensitive(conf, "ipv4DNSSecondary");
		snprintf(cmd, sizeof(cmd), "uci add_list network.wisp0.dns='%s'", ipv4DNSSecondary->valuestring);
		system(cmd);
	}
	system("uci commit network");
	return 0;
}

map<string, int (*)(const cJSON *req, char *rsp, int len)> srv_fnuc = {
	/*
	*/
	{ "UPGRADE", upgrade },
	{ "BASE_INFO", get_base_info },
	{ "SET_NETWORK_CFG", set_network_cfg },
	{ "GET_NETWORK_CFG", get_network_cfg },
};

int service_req_process(const char *msg, char *buf, int len)
{
	cJSON *json = cJSON_Parse(msg);
	cJSON *act = cJSON_GetObjectItemCaseSensitive(json, "Active");
	cJSON *params = cJSON_GetObjectItemCaseSensitive(json, "Params");
	if (srv_fnuc[act->valuestring]) {
		srv_fnuc[act->valuestring](params, buf, len);
	}
	cJSON_Delete(json);
	return 0;
}

int main()
{
	char buf[1024 * 8];
	for (;;) {
		if (recv_msg(SERVICE_QUEUE_REQ, buf, sizeof(buf)) > 0) {
			printf("recv msg: %s\n", buf);
			service_req_process(buf, buf, sizeof(buf));
			continue;
		}
	}
	return 0;
}